package org.ccccye.distributedlocks.redis;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * 基于redis的简单分布式锁
 */
@Component
public class RedisSimpleLock {
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 加锁
     * @param key
     * @param value
     * @return
     */
    public boolean tryLock(String key, String value) {
        return Optional.ofNullable(redisTemplate.opsForValue().setIfAbsent(key, value)).orElse(false);
    }

    /**
     * 加锁
     * @param key
     * @param value
     * @param timeout
     * @return
     */
    public boolean tryLock(String key, String value, int timeout) {
        return Optional.ofNullable(redisTemplate.opsForValue().setIfAbsent(key, value, timeout, TimeUnit.SECONDS)).orElse(false);
    }

    /**
     * 解锁
     * @param key
     * @return
     */
    public void unlock(String key, String value) {
        // 校验是否为自己的锁，防止锁被意外解除
        // 但是这样并不是原子操作
        // 不可重入
        if (value.equals(redisTemplate.opsForValue().get(key))){
            redisTemplate.opsForValue().getOperations().delete(key);
        }

//        Object currentValue = redisTemplate.opsForValue().get(key);
//        // 可优化：需要key+value都匹配再允许解锁
//        if (Objects.isNull(currentValue)) {
//            return true;
//        }
//
//        return Optional.ofNullable(redisTemplate.opsForValue().getOperations().delete(key)).orElse(false);
    }
}
